<?php

namespace App\Supports\Delivery;

use Carbon\Carbon;
use App\Models\Order;
use App\Events\OrderReceivedEvent;
use Illuminate\Support\Facades\Log;

class AutoReceiver
{
	protected $express;
	
	public function __construct()
	{
		$this->express = app(Express::class);
	}
	
	public function getAutoReceiveDays()
	{
		return 15;
	}
	
	protected function getExpress100(Order $order)
	{
		return $this->express->track($order, true);
	}
	
	protected function shouldBeReceived(Order $order)
	{
		if ($order->deliveryTime()) {
			$enforcedDeadline = $order->deliveryTime()->addDays($this->getAutoReceiveDays());
		} else {
			$enforcedDeadline = $order->created_at->addDays($this->getAutoReceiveDays());
		}
		
		if ($enforcedDeadline->lt(Carbon::now())) {
			return true;
		}
		
		$express100 = $this->getExpress100($order);
		if (empty($express100)) {
			return false;
		}
		
		$latestRecordIsChecked = isset($express100['ischeck']) ? (bool)$express100['ischeck'] : false;
		$latestRecordTime = isset($express100['data'][0]['time']) ? time_to_carbon($express100['data'][0]['time']) : Carbon::now();
		$receiveTime = $latestRecordTime->addDays($this->getAutoReceiveDays());
		if ($latestRecordIsChecked and Carbon::now()->gte($receiveTime)) {
			return true;
		}
		return false;
	}
	
	protected function receive()
	{
		Log::info('Today parcels receiving process has started...');
		
		Order::whereNotNull('paid_at')
			->whereNull('closed_at')->whereNull('cancelled_at')
			->where('delivery_status', 'delivered')
			->chunkById(100, function ($orders) {
				if ($orders->isEmpty()) {return false;}
				foreach ($orders as $order) {
					if ($this->shouldBeReceived($order)) {
						$order->update(['delivery_status' => 'received']);
						$order->items()->update(['delivery_status' => 'received']);
						event(new OrderReceivedEvent($order));
					}
					usleep(50);
				}
				return true;
			});
		
		Log::info('Today parcels receiving process has ended...');
	}
	
	public function __invoke()
	{
		$this->receive();
	}
}
